package cn.xuqiudong.rpc.extension.factory;

import cn.xuqiudong.rpc.common.annotathion.XqdExtension;
import cn.xuqiudong.rpc.common.util.PropertiesUtils;
import cn.xuqiudong.rpc.extension.XqdSpiExtensionLoader;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.xuqiudong.rpc.extension.XqdExtensionFactory;

/**
 * 描述:基于SPI的扩展工厂， 是单例
 * @author Vic.xu
 * @date 2022-02-14 17:30
 */
public class SpiXqdExtensionFactory implements XqdExtensionFactory {

    private Logger logger = LoggerFactory.getLogger(SpiXqdExtensionFactory.class);


    private static SpiXqdExtensionFactory instance = new SpiXqdExtensionFactory();

    private SpiXqdExtensionFactory(){}

    public static SpiXqdExtensionFactory getInstance(){
        return instance;
    }


    @Override
    public <T> T getXqdExtension(Class<T> type, String name) {
        if (type.isInterface() && type.isAnnotationPresent(XqdExtension.class)) {
            XqdSpiExtensionLoader<T> loader = XqdSpiExtensionLoader.getXqdExtensionLoader(type);
            return loader.getXqdExtension(name);
        }
        return null;
    }

    /**
     * 获取字使用的扩展， 根据配置，如果配置没有则 查使用默认的 扩展
     * @param type 接口类型
     * @param <T>
     * @return
     */
    @Override
    public <T> T getAdaptiveXqdExtension(Class<T> type) {
        if (type.isInterface() && type.isAnnotationPresent(XqdExtension.class)) {
            XqdSpiExtensionLoader<T> loader = XqdSpiExtensionLoader.getXqdExtensionLoader(type);

            XqdExtension annotation = type.getAnnotation(XqdExtension.class);
            String defaultName = getAdaptiveName(annotation);
            return loader.getXqdExtension(defaultName);
        }else {
            logger.warn(type.getSimpleName() + " 必须为接口且被XqdExtension标注");
        }
        return null;
    }


    /**
     * 获取适配的扩展点名称：如果配置了则使用配置的扩展点，没有配置，则使用默认的扩展点
     * @param annotation
     * @return
     */
    private static String getAdaptiveName(XqdExtension annotation){
        String key = annotation.configKey();
        if (StringUtils.isNotBlank(key)) {
            String configName = PropertiesUtils.getString(key);
            if (StringUtils.isNotBlank(configName)) {
                //返回配置的扩展name
                return configName;
            }
        }
        //返回默认的扩展
        return annotation.value();
    }
}
